<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';

import { useAppConfig } from '@vben/hooks';

import { ElMessage } from 'element-plus';
import mapboxgl from 'mapbox-gl';

import { historyApi } from '#/api';

const { mapboxAssetsIP } = useAppConfig(import.meta.env, import.meta.env.PROD);
const mapContainer = ref<HTMLDivElement | null>(null);
const map = ref<mapboxgl.Map | null>(null);
const inputYear = ref(1);
const loading = ref(false);

const yearRange = {
  min: -3200,
  max: 1900,
};
const displayYear = ref(inputYear.value); // 实际加载的年份

const formattedDisplayYear = computed(() => {
  const year = displayYear.value;
  if (year < 0) return `BC ${-year}`;
  return `AD ${year}`;
});

function findAvailableYear(year: number): number {
  if (year === 0) return 1;
  if (year > 0) {
    return year; // AD1–AD1900，每年都有
  } else if (year >= -1000) {
    return year; // BC1–BC1000，每年都有
  } else {
    return Math.round(year / 10) * 10;
  }
}

const formattedYear = computed(() => {
  const year = inputYear.value;
  if (year < 0) return `BC ${Math.abs(year)}`;
  return `AD ${year}`;
});

function changeYear(offset: number) {
  let newYear = inputYear.value + offset;
  newYear = Math.min(Math.max(newYear, yearRange.min), yearRange.max);
  if (newYear === 0) {
    newYear += offset;
  }
  inputYear.value = newYear;
}

function onInputChange() {
  inputYear.value = Math.min(
    Math.max(inputYear.value, yearRange.min),
    yearRange.max,
  );
  if (inputYear.value === 0) inputYear.value = 1;
}

async function loadMapStyle(_year: number) {
  if (!map.value) return;

  // 非法年份（如 "-"）直接跳过，不提示错误
  if (typeof _year !== 'number' || Number.isNaN(_year)) return;

  loading.value = true;
  try {
    const availableYear = findAvailableYear(_year);
    displayYear.value = availableYear;

    const formatted =
      availableYear < 0 ? `BC${-availableYear}` : `AD${availableYear}`;
    const response = await fetch(historyApi.getHistoryMapStyle(formatted));
    if (!response.ok) throw new Error('样式加载失败');
    const style = await response.json();
    style.glyphs = `${mapboxAssetsIP}/glyphs/fonts/{fontstack}/{range}.pbf`;
    style.sprite = `${mapboxAssetsIP}/sprites/mapStudio/sprite`;
    map.value.setStyle(style);

    if (availableYear !== _year) {
      ElMessage.info(
        `没有 ${formattedYear.value} 的地图，显示的是最接近的 ${formattedDisplayYear.value}`,
      );
    }
  } catch (error) {
    console.error('加载失败:', error);
    ElMessage.error('样式加载失败');
  } finally {
    loading.value = false;
  }
}

onMounted(async () => {
  mapboxgl.accessToken =
    'pk.eyJ1IjoieWNzb2t1IiwiYSI6ImNrenozdWdodDAza3EzY3BtdHh4cm5pangifQ.ZigfygDi2bK4HXY1pWh-wg';

  loading.value = true;

  try {
    const formatted = formattedYear.value.replace(' ', '');
    const response = await fetch(historyApi.getHistoryMapStyle(formatted));
    if (!response.ok) throw new Error('样式加载失败');
    const style = await response.json();

    map.value = new mapboxgl.Map({
      container: mapContainer.value!,
      style, // 初始就使用目标年份样式
      center: [116.4074, 39.9042],
      zoom: 3,
      projection: 'mercator',
    });

    map.value.on('load', () => {
      // 这里无需再次调用 loadMapStyle
    });

    map.value.addControl(new mapboxgl.NavigationControl(), 'top-left');
    map.value.addControl(new mapboxgl.ScaleControl(), 'bottom-left');
  } catch (error) {
    console.error('初始地图加载失败:', error);
    ElMessage.error('初始样式加载失败');
  } finally {
    loading.value = false;
  }
});

watch(inputYear, (newYear) => {
  loadMapStyle(newYear);
});
</script>

<template>
  <div class="relative h-full w-full">
    <div ref="mapContainer" class="h-full w-full"></div>

    <div
      class="absolute bottom-4 right-4 z-10 w-72 rounded bg-white/90 p-4 shadow-lg backdrop-blur-sm"
    >
      <div class="mb-2 flex items-center justify-between">
        <button
          @click="changeYear(-1)"
          class="rounded border px-3 py-1 hover:bg-gray-100"
          :disabled="inputYear <= yearRange.min"
        >
          ←
        </button>
        <input
          v-model.number="inputYear"
          @change="onInputChange"
          type="number"
          class="w-24 border px-2 py-1 text-center"
          :min="yearRange.min"
          :max="yearRange.max"
        />
        <button
          @click="changeYear(1)"
          class="rounded border px-3 py-1 hover:bg-gray-100"
          :disabled="inputYear >= yearRange.max"
        >
          →
        </button>
      </div>
      <div class="text-center font-bold">
        当前年份: {{ formattedDisplayYear }}
      </div>
    </div>

    <div
      v-if="loading"
      class="absolute left-1/2 top-1/2 z-20 -translate-x-1/2 -translate-y-1/2 transform rounded-lg bg-white/90 px-6 py-4 text-gray-700 shadow-lg backdrop-blur-sm"
    >
      加载历史地图数据中...
    </div>
  </div>
</template>

<style scoped>
button:disabled {
  @apply cursor-not-allowed opacity-50 hover:bg-transparent;
}

:deep(.mapboxgl-ctrl-logo) {
  display: none !important;
}
</style>
